package com.youlu.campus.service.english;

import com.alibaba.fastjson.JSON;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.ActivityTaskInfo;
import com.youlu.campus.entity.UserPO;
import com.youlu.campus.entity.english.UserCompetition;
import com.youlu.campus.entity.english.vo.request.CreateUserCompetitionCommand;
import com.youlu.campus.entity.english.vo.request.UserCompetitionFeeQuery;
import com.youlu.campus.entity.enums.TaskBizType;
import com.youlu.campus.service.activity.ActivityTaskService;
import com.youlu.campus.service.invite.UserInviteRecordService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UserCompetitionService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private StringRedisTemplate redisTemplate;

    private final static String CACHE_USER = "campus:competition:english:%s";

    @Autowired
    @Lazy
    private UserCompetitionFeeService userCompetitionFeeService;

    @Autowired
    private UserInviteRecordService userInviteRecordService;

    @Autowired
    private ActivityTaskService activityTaskService;
    @Lazy
    @Autowired
    private UserCompetitionQaService userCompetitionQaService;
    @Value("${spring.profiles.active}")
    private String env;

    private final static String ACTIVITY_TEST = "6160f088ff34156f180ef9f0";
    private final static String ACTIVITY_PROD = "61834be460d5e86411b654a5";


    public void updateUserInfo(UserCompetition updateUserCompetition){
        if(StringUtils.isBlank(updateUserCompetition.getId())||StringUtils.isBlank(updateUserCompetition.getUserId())){
            throw new BusinessException("参数错误");
        }
        updateUserCompetition.setUpdatedTime(new Date());
        this.mongoTemplate.save(updateUserCompetition);
        redisTemplate.delete(String.format(CACHE_USER,updateUserCompetition.getUserId()));
        userCompetitionFeeService.updateUserInfo(updateUserCompetition);
        userCompetitionQaService.updateUserInfo(updateUserCompetition);

    }

    public UserCompetition detail(String id){
        return this.mongoTemplate.findById(id,UserCompetition.class);
    }

   public Page<UserCompetition> list(UserCompetitionFeeQuery userCompetitionFeeQuery){
       String mobile = userCompetitionFeeQuery.getMobile();
       String universityId = userCompetitionFeeQuery.getUniversityId();
       Query query = new Query();
       if(StringUtils.isNotBlank(mobile)){
           query.addCriteria(Criteria.where("mobile").is(mobile));
       }
       if(StringUtils.isNotBlank(universityId)){
           query.addCriteria(Criteria.where("universityId").is(universityId));
       }
       PageRequest pageRequest = PageRequest.of(userCompetitionFeeQuery.getPageNo() - 1, userCompetitionFeeQuery.getPageSize());
       long count = this.mongoTemplate.count(query, UserCompetition.class);
       if(count==0){
           return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> 0);
       }
       query.with(Sort.by(Sort.Direction.DESC,"createdTime"));
       List<UserCompetition> list = this.mongoTemplate.find(query.with(pageRequest), UserCompetition.class);
       list.stream().map(userCompetition -> {
           String buyItem = userCompetitionFeeService.feeByUserId(userCompetition.getUserId());
           if(StringUtils.isNotBlank(buyItem)){
               userCompetition.setBuy(Boolean.TRUE);
               userCompetition.setItem(buyItem);
           }
           String activityId = ACTIVITY_TEST;
           if("prod".equals(env)){
               activityId = ACTIVITY_PROD;
           }
           ActivityTaskInfo activityTaskInfo = activityTaskService.find(activityId, TaskBizType.INVITE);
           Long inviteUserCount = userInviteRecordService.getInviteUserCount(userCompetition.getUserId(), activityId, activityTaskInfo.getId(), Boolean.TRUE);
           userCompetition.setInviteUserCount(inviteUserCount);
           return userCompetition;
       }).collect(Collectors.toList());

       return PageableExecutionUtils.getPage(list, pageRequest, () -> 5000);
    }



     public UserCompetition findByMobile(String mobile){
         Query query = new Query();
         query.addCriteria(Criteria.where("mobile").is(mobile));
         return this.mongoTemplate.findOne(query,UserCompetition.class);
     }

    public void register(CreateUserCompetitionCommand createUserCommand){
        UserPO currentUser = createUserCommand.getCurrentUser();
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(currentUser.getId()));
        boolean exists = this.mongoTemplate.exists(query, UserCompetition.class);
        if(exists){
           throw new BusinessException("你已报名，无须重复报名");
        }
        UserCompetition userCompetition = new UserCompetition();
        userCompetition.setUserId(currentUser.getId());
        userCompetition.setOpenId(currentUser.getOpenId());
        userCompetition.setMobile(createUserCommand.getMobile());
        userCompetition.setName(createUserCommand.getName());
        userCompetition.setUniversityId(createUserCommand.getUniversityId());
        userCompetition.setUniversityName(createUserCommand.getUniversityName());
        userCompetition.setNickName(currentUser.getNickName());
        userCompetition.setAvatarUrl(currentUser.getAvatarUrl());
        this.mongoTemplate.save(userCompetition);
        this.redisTemplate.opsForValue().set(String.format(CACHE_USER,currentUser.getId()), JSON.toJSONString(userCompetition),40L, TimeUnit.HOURS);
    }

    public Boolean exist(String currentUserId){
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(currentUserId));
       return this.mongoTemplate.exists(query, UserCompetition.class);
    }
   public UserCompetition findByUserId(String userId){
        String cacheUserId = String.format(CACHE_USER,userId);
       String jsonExist = redisTemplate.opsForValue().get(cacheUserId);
       if(StringUtils.isNotBlank(jsonExist)){
          return JSON.parseObject(jsonExist,UserCompetition.class);
       }
       Query query = new Query();
       query.addCriteria(Criteria.where("userId").is(userId));
       return this.mongoTemplate.findOne(query, UserCompetition.class);
   }

}
